﻿using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Hosting.Internal;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using System.Diagnostics;
using System.IO;
using System.Windows;
using System.Windows.Navigation;
using XYAC.Framework.MonitorTireMaterialOnline.Context;
using XYAC.Framework.MonitorTireMaterialOnline.Extensions;
using XYAC.Framework.MonitorTireMaterialOnline.IServices;
using XYAC.Framework.MonitorTireMaterialOnline.LocalData.Context;
using XYAC.Framework.MonitorTireMaterialOnline.OracleRemoteDB;
using XYAC.Framework.MonitorTireMaterialOnline.Services;
using XYAC.Framework.MonitorTireMaterialOnline.ViewModels;
using XYAC.Framework.MonitorTireMaterialOnline.Views;
using XYAC.Framework.WatchDog;

namespace XYAC.Framework.MonitorTireMaterialOnline
{
    /// <summary>
    /// Interaction logic for App.xaml
    /// </summary>
    public partial class App : Application
    {
        /// <summary>
        /// 
        /// </summary>
        public App()
        {
            Environment.CurrentDirectory = System.IO.Path.GetDirectoryName(this.GetType().Assembly.Location);//设置工作目录
            try
            {
                this.EventWaitHandle = new EventWaitHandle(false, EventResetMode.AutoReset, ProcessSingleInstance.EventName);
                ThreadPool.RegisterWaitForSingleObject(this.EventWaitHandle, OnOtherInstanceStarted, null, Timeout.Infinite, true);
            }
            catch (Exception)
            {

            }
            AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
            Current.DispatcherUnhandledException += Current_DispatcherUnhandledException;
            this.Tray = new TrayIconManager();
        }

        private void Current_DispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
        {
            RestartApplication();
        }

        private void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
        {
            //未处理的异常
            RestartApplication();
        }
        private void OnOtherInstanceStarted(object state, bool timedOut)
        {
            try
            {
                // 当检测到其他实例启动时，激活当前实例的主窗口
                Application.Current.MainWindow.Dispatcher.Invoke(new Action(ActivateMainWindow));
                //this.EventWaitHandle.Reset();
            }
            catch (Exception)
            {

            }
        }

        private static void RestartApplication()
        {
            // 获取当前应用程序的启动路径
            ProcessStartInfo startInfo = new ProcessStartInfo
            {
                FileName = "DelayStart.vbs", // 或者是 "Delay.bat"
                UseShellExecute = true
            };
            //灾难性故障时重新启动
            Process.Start(startInfo);
        }

        /// <summary>
        /// 日志记录器
        /// </summary>
        private ILogger<App> Logger { get; set; }

        public IHost HostService { get; private set; }
        public EventWaitHandle EventWaitHandle { get; }
        public TrayIconManager Tray { get; }

        protected override void OnStartup(StartupEventArgs e)
        {
            if (ProcessSingleInstance.AlreadyRunning2())
            {

                Application.Current.Shutdown();
                return;
            }
            else
            {
                RigisterDI();
                this.HostService.Start();

                AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;





                using (var scope = HostService.Services.CreateScope())
                {
                    var localDbService = scope.ServiceProvider.GetService<ILocalDataService>();
                    var ret = localDbService.CreateDb();

                    //var remoteDbService = scope.ServiceProvider.GetService<OracleMesContext>();
                    //var ret2 = remoteDbService.Database.EnsureCreated();
                }

            }




            base.OnStartup(e);
            try
            {
                if (this.HostService != null)
                {
                    var mainWindow = HostService.Services.GetRequiredService<MainWindow>();
                    ///Application.Current.MainWindow = mainWindow;
                    mainWindow.Show();

                }
            }
            catch (Exception)
            {

            }
            WatchDogStarter.StartWatchDog();//启动进程看门狗
        }
        private void ActivateMainWindow()
        {
            var mainWindow = Application.Current.MainWindow;
            if (mainWindow != null)
            {
                mainWindow.Show();
                mainWindow.Activate();
            }
        }

        private void RigisterDI()
        {

            #region 注册DI服务
            var host = Host.CreateDefaultBuilder();

            host.ConfigureLogging(option =>
            {
                // 清除所有默认的日志提供程序
                option.ClearProviders();
                //option.AddProvider(new Log4NetProvider("log4net.config", true));
                option.AddLog4Net("log4net.config");

            });
            host.ConfigureAppConfiguration((hostingContext, config) =>
            {
                var fullPath = Path.GetFullPath(Path.Combine(Directory.GetCurrentDirectory(), "Configs"));
                config.SetBasePath(fullPath)
                .AddJsonFile("AppConfig.json", optional: false, reloadOnChange: true);
            });
            host.ConfigureServices((hostContext, services) => ConfigureServices(hostContext.Configuration, services));
            this.HostService = host.Build();
            DeleteSuccessFlag();
            this.Logger = this.HostService.Services.GetRequiredService<ILogger<App>>();

            InitializeDatabase();
            #endregion
        }
        private void CreateSuccessFlag()
        {
            try
            {

                using (FileStream fs = File.Create("CorrectHandle"))
                {

                }
            }
            catch (Exception)
            {

            }
        }
        private void DeleteSuccessFlag()
        {
            try
            {

                File.Delete("CorrectHandle");
            }
            catch (Exception)
            {

            }
        }
        private void InitializeDatabase()
        {
            try
            {
                IOptionsMonitor<AppConfig> appConfig = null;
                using (var scope = this.HostService.Services.CreateScope())
                {
                    appConfig = scope.ServiceProvider.GetService<IOptionsMonitor<AppConfig>>();
                }


                //创建本地主数据库
                using (var scope = this.HostService.Services.CreateScope())
                {
                    try
                    {
                        using (var context = scope.ServiceProvider.GetService<LocalDataContext>())
                        {
                            var ret = context.Database.EnsureCreated();//创建当前数据库

                        }

                    }
                    catch (Exception ex)
                    {
                        this.Logger?.LogError("创建本地主数据库失败", ex);
                    }
                }
                //创建当日报表数据库
                using (var scope = this.HostService.Services.CreateScope())
                {
                    try
                    {
                        using (var context = scope.ServiceProvider.GetService<CurrentReportContext>())
                        {
                            context.GetDbFileCreated();
                            var ret = context.Database.EnsureCreated();//创建当前数据库

                        };
                    }
                    catch (Exception ex)
                    {
                        this.Logger?.LogError("创建本地主数据库失败", ex);

                    }
                }

                //创建昨日报表数据库
                {
                    using (var context = new CustomReportContext(appConfig, DateOnly.FromDateTime(DateTime.Now.Date.AddDays(-1))))
                    {
                        try
                        {
                            var ret = context.Database.EnsureCreated();//创建当前数据库

                        }
                        catch (Exception ex)
                        {
                            this.Logger?.LogError("创建昨日报表数据库失败", ex);

                        }
                    };

                }
            }
            catch (Exception ex)
            {
                this.Logger?.LogError(ex.Message, ex);
            }
        }

        private void ConfigureServices(IConfiguration configuration, IServiceCollection services)
        {
            #region 注册数据上下文
            services.AddDbContext<CurrentReportContext>();
            services.AddDbContext<CurrentHisDataContext>();
            services.AddDbContext<DatabaseContext>();
            services.AddDbContext<LocalDataContext>();
            services.AddDbContext<OracleMesContext>();



            services.AddTransient<ILocalReportService, LocalReportService>();
            services.AddTransient<IDatabaseService, DatabaseService>();
            services.AddTransient<IHisDataService, HisDataService>();

            services.AddTransient<ILocalDataService, LocalDataService>();
            services.AddTransient<IYB_TechnologyService, YB_TechnologyService>();
            services.AddTransient<IYB_LOT_INSPECTService, YB_LOT_INSPECTService>();
            services.AddTransient<IYB_LOT_INSPECT_LocalService, YB_LOT_INSPECT_LocalService>();
            services.AddTransient<YB_PROCESS_STEPService>();
            //services.AddTransient<AccessCAreaService>();
            services.AddTransient<IHyperDbService, HyperDbService>();
            services.AddTransient<IYB_LOT_INSPECTService, YB_LOT_INSPECTService>();

            services.AddSingleton<MainWindow>();
            services.AddSingleton<MainWindowViewModel>();

            services.AddSingleton<QualityDataHistoryView>();
            services.AddSingleton<QualityDataHistoryViewModel>();


            services.AddSingleton<SystemConfigView>();
            services.AddSingleton<SystemConfigViewModel>();



            services.AddSingleton<TrayIconManager>();

            // 注册配置到服务容器

            //services.AddOptions();
            // 使用配置实例配置 AppConfig
            //services.Configure<AppConfig>(configuration);
            services.Configure<AppConfig>(configuration.GetSection("AppConfig"));
            #endregion
        }


    }


}
